## -*- coding: utf-8 -*-
from functools import reduce

from Constant import register, DB, ATTR, GLOSS, \
                        showDoc, CON, INS, getInverseRel, REL, RULE

def choice_add(db, conIds, attr):
    print('库中存在该{} '.format(attr))
    find_doc = db.find_con_by_id if attr in [CON, INS] else db.find_rel_by_id
    for i in range(len(conIds)):
        print('------------ No.{}--------------'.format(i + 1))
        print(showDoc(db, find_doc(conIds[i])))
    return input('是否插入该{}   y/n \n'.format(attr)) == 'y'


transFuncMap = {}

@register(transFuncMap, '概念+=')
def trans_add_con(db: DB, cons: list) -> list:
    res = []
    for idx, conIds in zip(range(len(cons)), [db.cname2id(con) for con in cons]):
        if len(conIds) == 0 or choice_add(db, conIds, CON):
            res.append(cons[idx])
    return res

@register(transFuncMap, '实例+=')
def trans_add_ins(db: DB, inss: list) -> list:
    res = []
    for idx, insIds in zip(range(len(inss)), [db.cname2id(ins) for ins in inss]):
        if len(insIds) == 0 or choice_add(db, insIds, CON):
            res.append(inss[idx])
    return res

@register(transFuncMap, '属性+=')
def trans_add_attr(db: DB, attrs: list) -> list:
    res = []
    for idx, attrIds in zip(range(len(attrs)), [db.rname2id(attr) for attr in attrs]):
        if len(attrIds) == 0 or choice_add(db, attrIds, ATTR):
            res.append(attrs[idx])
    return res

@register(transFuncMap, '关系+=')
def trans_add_rel(db: DB, rels: list) -> list:
    res = []
    for idx, relIds in zip(range(len(rels)), [db.rname2id(rel) for rel in rels]):
        if len(relIds) == 0 or choice_add(db, relIds, REL):
            res.append(rels[idx])
    return res

# @register(transFuncMap, '规则+=')
# def trans_add_rule(db: DB, rule: str) -> str:
#     ruleIds = db.rname2id(rule)
#     if len(ruleIds) == 0 or choice_add(db, ruleIds, RULE):
#         return rule
#     return ''


def chice_del(db, conIds, attr):
    find_func = db.find_con_by_id if attr in [CON, INS] else db.find_rel_by_id
    print('库中存在多个{}'.format(attr))
    for i in range(len(conIds)):
        print('----------{}----------'.format(i+1))
        print(showDoc(db, find_func(conIds[i])))
    res = int(input('请选择 你要删除的{}， 输入0都不删除\n'.format(attr)))
    if res == 0:
        return []
    return [conIds[res - 1]]

def trans_del(db, terms, attr):
    res = []
    for termIds in [db.cname2id(term) for term in terms]:
        if len(termIds) == 0:
            print('概念不存在')
        elif len(termIds) > 1:
            res += chice_del(db, termIds, attr)
        else:
            res.append(termIds[0])
    return res
    

@register(transFuncMap, '概念-=')
def trans_del_con(db: DB, cons: list) -> list:
    return trans_del(db, cons, CON)

@register(transFuncMap, '实例-=')
def trans_del_ins(db: DB, inss: list) -> list:
    return trans_del(db, inss, INS)

@register(transFuncMap, '属性-=')
def trans_del_attr(db: DB, attrs: list) -> list:
    return trans_del(db, attrs, ATTR)

@register(transFuncMap, '关系-=')
def trans_del_rel(db: DB, rels: list) -> list:
    return trans_del(db, rels, REL)

@register(transFuncMap, '规则-=')
def trans_del_rule(db: DB, rules: list) -> list:
    return trans_del(db, rules, RULE)



def trans_term_to_id(db:DB, term:str, attr:str):
    termIds = (db.cname2id if attr in [INS, CON] else db.rname2id)(term)
    if len(termIds) == 1:
        return termIds[0]
    if len(termIds) == 0:
        print('库中不存在 {} {} '.format(attr, term))
        return None
    func = db.find_con_by_id if attr in [INS, CON] else db.find_rel_by_id
    print('库中存在多个{} 请选择你需要的 0为不选择'.format(term))
    for i in range(len(termIds)):
        print('----------{}----------'.format(i+1))
        showDoc(db, func(termIds[i]))
    idx = int(input('请选择'))
    if idx == 0:
        return None
    return termIds[idx-1]


@register(transFuncMap, '+')
def trans_create_conn(db: DB, con1, rel, con2) -> list:
    con1 = trans_term_to_id(db, con1[0], CON)
    rel = trans_term_to_id(db, rel[0], REL)
    con2 = trans_term_to_id(db, con2[0], CON)
    if con1 and rel and con2:
        return [con1, rel, con2]
    return []

@register(transFuncMap, '-')
def trans_break_conn(db: DB, con1, rel, con2 :str) -> list:
    con1 = trans_term_to_id(db, con1[0], CON)
    rel = trans_term_to_id(db, rel[0], REL)
    con2 = trans_term_to_id(db, con2[0], CON)
    if con1 and rel and con2:
        return [con1, rel, con2]
    return []

@register(transFuncMap, '+=')
def trans_add_rel_value(db: DB, con1s, rels, con2s: list) -> list:
    con1Id = trans_term_to_id(db, con1s[0], CON)
    relId = trans_term_to_id(db, rels[0], REL)
    con2sIds = [trans_term_to_id(db, con2, CON) for con2 in con2s]
    if con1Id and relId and reduce(lambda a, b: a and b, con2sIds):
        return [con1Id, relId, con2sIds]
    return []

@register(transFuncMap, '-=')
def trans_pull_rel_value(db: DB, con1s, rels, con2s: list) -> list:
    con1Id = trans_term_to_id(db, con1s[0], CON)
    relId = trans_term_to_id(db, rels[0], REL)
    con2sIds = [trans_term_to_id(db, con2, CON) for con2 in con2s]
    if con1Id and relId and reduce(lambda a, b: a and b, con2sIds):
        return [con1Id, relId, con2sIds]
    return []

@register(transFuncMap, 'child+=')
def trans_add_child(db: DB,  parent: str, children: list) -> list:
    parId = trans_term_to_id(db, parent, CON)
    childIds = [trans_term_to_id(db, child, CON) for child in children]
    if parId and reduce(lambda a,b: a and b, childIds):
        return [parId, childIds]
    return []

@register(transFuncMap, 'child-=')
def trans_del_child(db: DB,  parent: str, children: list) -> list:
    parId = trans_term_to_id(db, parent, CON)
    childIds = [trans_term_to_id(db, child, CON) for child in children]
    if parId and reduce(lambda a,b: a and b, childIds):
        return [parId, childIds]
    return []

@register(transFuncMap, 'name=')
def trans_set_name(db: DB, term: str, newNames):
    attr = input('请输入要改变的term的属性 {}/{}/{}/{}/{}'.format(CON, INS, REL, ATTR, RULE))
    termId = trans_term_to_id(db, term, attr)
    return not termId or (termId, newNames)


@register(transFuncMap, 'name+=')
def trans_add_name(db: DB, term: str, newNames=None):
    attr = input('请输入要改变的term的属性 {}/{}/{}/{}/{}'.format(CON, INS, REL, ATTR, RULE))
    termId = trans_term_to_id(db, term, attr)
    return not termId or (termId, attr, newNames)

@register(transFuncMap, 'name-=')
def trans_del_name(db: DB, term: str, newNames=None):
    attr = input('请输入要改变的term的属性 {}/{}/{}/{}/{}'.format(CON, INS, REL, ATTR, RULE))
    termId = trans_term_to_id(db, term, attr)
    return not termId or (termId, attr, newNames)

@register(transFuncMap,  ATTR + '=')
def trans_upd_property(db: DB, term: str, updprop=None):
    updprop = updprop[0]
    attr = {'实例': INS, '概念': CON, '关系': REL, '属性': ATTR}[updprop]
    termId = trans_term_to_id(db, term, attr)
    if termId:
        return termId, attr
    return None


@register(transFuncMap,  GLOSS + '=')
def trans_upd_term_glosee(db: DB, term: str, gloss=None):
    attr = input('请输入要改变的term的属性 {}/{}/{}/{}/{}'.format(CON, INS, REL, ATTR, RULE))
    termId = trans_term_to_id(db, term, attr)
    if termId:
        return termId, attr, gloss[0]
    return None



# def trans_add_var(db: DB, varName, varValue) -> tuple:
#     return varName, varValue
#
# def trans_query(db: DB, *triple):
#     return triple
if __name__ == '__main__':
    for k, v in transFuncMap.items():
        print(k, v)